#include "app.h"
#include "../net/net.h"

#ifdef MAIN_MODULE
#include "../main_module/main_module.h"
#else
#include "../sub_module/sub_module.h"
#endif // MAIN_MODULE

static uint8 g_aes_key[16];

void app_init()
{
  memset(g_aes_key, 0xff, sizeof(g_aes_key));

#ifdef MAIN_MODULE
  main_module_init();
#else
  sub_module_init();
#endif // MAIN_MODULE
}

void *app_get_trans_payload()
{
  app_header_t *app = net_get_trans_payload();

  return app->payload;
}

void app_rf_recv_deal(uint8 *data, uint8 len, uint8 *segaddr, uint8 srcaddr, uint8 dstaddr, uint8 rssi)
{
  if(dstaddr != NWK_BROADCAST_ADDR  && srcaddr != NWK_NULL_ADDR)
  {
    app_decrypt(srcaddr, data, len - NWK_END_CONTENT_LEN);
  }

#ifdef MAIN_MODULE
  main_module_recv_deal(data, len, segaddr, srcaddr, dstaddr, rssi);
#else
  sub_module_recv_deal(data, len, segaddr, srcaddr, dstaddr, rssi);
#endif // MAIN_MODULE`
}

uint8 app_transmit(uint8 type, uint8 addr, uint8 len)
{
  app_header_t *app = net_get_trans_payload();
  app->type = type;

  if(addr != NWK_BROADCAST_ADDR  && net_get_myaddr() != NWK_NULL_ADDR)
  {
    app_encrypt(addr, app, len + sizeof(app_header_t));
  }
  return net_transmit(addr, sizeof(app_header_t) + len);
}

void app_encrypt(uint8 addr, void *data, uint8 len)
{
  uint8 *tmp_key;
  tmp_key = app_get_key(addr);
  if(tmp_key != NULL)
  {
    memcpy(g_aes_key, tmp_key, NETKEY_LEN);
    //hal_aes_encrypt(data, data, len, g_aes_key);
		AesCTREncrypt(data,data,len,g_aes_key,16);
  }
}

void app_decrypt(uint8 addr, void *data, uint8 len)
{
  uint8 *tmp_key;
  tmp_key = app_get_key(addr);
  if(tmp_key != NULL)
  {
    memcpy(g_aes_key, tmp_key, NETKEY_LEN);
    AesCTRDecrypt(data, data, len, g_aes_key,16);
  }
}

uint8 *app_get_key(uint8 addr)
{
#ifdef MAIN_MODULE
  return main_module_get_key(addr);
#else
  return sub_module_get_key(addr);
#endif // MAIN_MODULE
}

void app_poll()
{
#ifdef MAIN_MODULE
  main_module_poll();
#else
  sub_module_poll();
#endif // MAIN_MODULE
}

void app_ack_sync_content_cb(uint8 *data, uint8 len)
{
#ifdef MAIN_MODULE
  main_module_ack_sync_content_cb(data, len);
#else
  sub_module_ack_sync_content_cb(data, len);
#endif // MAIN_MODULE
}

uint8 app_ack_sync_content_set(uint8 *data)
{
#ifdef MAIN_MODULE
  return main_module_ack_sync_content_set(data);
#else
  return sub_module_ack_sync_content_set(data);
#endif // MAIN_MODULE
}
